
此系列文章是以我的業餘專案: Kimoji 作為範例。
這款以純 Jetpack Compose 撰寫的 side project,已經在 Google Play 上架。 歡迎試玩!
立馬下載
索取兌換碼
當部分 UI invalid 時,Compose 會盡可能只針對需要更新的部分進行 recompose。舉例來說,Compose 可能會重新執行一個 button 的 composable,而不執行該元件在 UI 樹狀結構中任何上層或下層的 composables。
每個 composable function 和 lambda 都可能會自行 recompose。下面的範例顯示了 recomposition 在 render 清單時如何略過部分元件:
/**
 * Display a list of diaries the user can click with a header
 */
@Composable
fun Journal(
    header: String,
    diaries: List<String>,
    onDiaryClick: (String) -> Unit
) {
    Column {
        // this will recompose when [header] changes, but not when [diaries] changes
        Text(header, style = MaterialTheme.typography.h5)
        Divider()
        // LazyColumn is the Compose version of a RecyclerView.
        // The lambda passed to items() is similar to a RecyclerView.ViewHolder.
        LazyColumn {
            items(diaries) { notes ->
                // When an item's [notes] updates, the adapter for that item
                // will recompose. This will not recompose when [header] changes
                DiaryItem(notes, onDiaryClick)
            }
        }
    }
}
/**
 * Display a single diary the user can click.
 */
@Composable
private fun DiaryItem(notes: String, onClick: (String) -> Unit) {
    Text(notes, Modifier.clickable(onClick = { onClick(notes) }))
}
上面這段 code 的各個 scope 都可能是 recomposition 期間唯一會執行的項目。當 header 變更時,Compose 可能會直接執行 Column 的 lambda,而不會執行它的任何的 parent。另外,在執行 Column 時,如果 diaries 沒有變更,Compose 可能會選擇略過 LazyColumn 的 items。
同樣地,執行所有 composable function 或 lambda 都不應該有任何 side-effect。當我們需要執行 side-effect 時,需透過 callback 觸發。
只要 Compose 認為 composable 的參數可能有變動,即會啟動 recomposition。Recomposition 具有「optimistic」的特性,這表示 Compose 預期在參數再次變更前可以完成 recomposition。如果參數在 recomposition 完成前就「有變動」,Compose 可能會取消這個 recomposition,並使用新的參數重新啟動 recomposition。
Recomposition 取消後,Compose 會捨棄 recomposition 中的 UI 樹狀結構。如果顯示的 UI 有任何 side-effect,即使 composition 取消,系統仍會套用 side-effect。這可能會導致 app 狀態不一致。
要確認所有 composable function 和 lambda 皆符合 idempotent、無 side-effect 的條件,以處理具有 optimistic 特性的 recomposition。
此系列文章是以我的業餘專案:Kimoji 為範例。
Kimoji 是一款心情日記 App,讓你用可愛的 emoji 來撰寫你的心情日記。現在就來試試這款設計精美的微日記吧!
立馬下載
索取兌換碼
Reference: https://developer.android.com/jetpack/compose/mental-model